﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WebCore.Models.ViewModels.Account;
using WebCore.Models.DataEntities;
using System.Web.Security;
using WebCore.App_Start;
using WebCore.Models.ViewModels.Admin;

namespace WebCore.Models.DataManagers
{
    public class AccountManager
    {
        public static bool IsValidUser(RegisterViewModel viewModel, ref string errorCode)
        {
            WebCore.Models.DataEntities.DataEntities entities = new DataEntities.DataEntities();

            //
            if (viewModel.Password != viewModel.PasswordConfirm)
            {
                errorCode = "NotMatchPassword";
                return false;
            }
            //
            List<User> existingUserName = (from r in entities.Users
                                           where r.UserName.ToUpper() == viewModel.UserName.ToUpper()
                                           select r).ToList();
            if (existingUserName.Count > 0)
            {
                errorCode = "ExistedUserName";
                return false;
            }
            //
            List<UserDetail> existingEmail = (from r in entities.UserDetails
                                              where r.Email.ToUpper() == viewModel.Email.ToUpper()
                                              select r).ToList();
            if (existingEmail.Count > 0)
            {
                errorCode = "ExistedEmail";
                return false;
            }
            //
            return true;
        }

        public static UserDetail GetUserDetail(string userName)
        {
            WebCore.Models.DataEntities.DataEntities entities = new DataEntities.DataEntities();
            User user = (from r in entities.Users
                         where r.UserName == userName
                         select r).FirstOrDefault();
            UserDetail detail = (from r in entities.UserDetails
                                 where r.UserID == user.UserId
                                 select r).FirstOrDefault();
            return detail;
        }

        public static UserDetail GetUserDetail(string userName, ref bool isLocked)
        {
            isLocked = false;
            WebCore.Models.DataEntities.DataEntities entities = new DataEntities.DataEntities();
            User user = (from r in entities.Users
                         where r.UserName == userName
                         select r).FirstOrDefault();
            if (user == null) return null;
            DataEntities.Membership membership = (from r in entities.Memberships
                                                  where r.UserId == user.UserId
                                                  select r).FirstOrDefault();
            if (membership == null) return null;
            UserDetail detail = (from r in entities.UserDetails
                                 where r.UserID == user.UserId
                                 select r).FirstOrDefault();
            if (detail == null) return null;
            if (membership.IsLockedOut)
            {
                isLocked = true;
                detail.State = MyAppConfig.State_Locked;
                entities.SaveChanges();
                return detail;
            }
            isLocked = false;
            return detail;
        }

        public static UserDetail CreateUser(RegisterViewModel viewModel, Guid activeCode)
        {
            MembershipUser memUser = System.Web.Security.Membership.CreateUser(viewModel.UserName, viewModel.Password);
            memUser.Email = viewModel.Email;
            memUser.IsApproved = false;

            System.Web.Security.Membership.UpdateUser(memUser);

            WebCore.Models.DataEntities.DataEntities entities = new DataEntities.DataEntities();
            User user = (from r in entities.Users
                         where r.UserName == memUser.UserName
                         select r).FirstOrDefault();
            UserDetail detail = new UserDetail();
            detail.UserName = user.UserName;
            detail.CreatedDate = memUser.CreationDate;
            detail.UserDetailID = Guid.NewGuid();
            detail.UserID = user.UserId;
            detail.FullName = viewModel.FullName;
            detail.Gender = viewModel.Gender == "MALE" ? true : false;
            detail.HomeMobile = viewModel.PhoneMobile;
            detail.HomePhone = viewModel.PhoneHome;
            detail.Address = viewModel.Address;
            detail.BirthDate = DateTime.Parse(viewModel.BirthDate + "/" + viewModel.BirthMonth + "/" + viewModel.BirthYear);
            detail.ActivateCode = activeCode;
            detail.State = MyAppConfig.State_Inactive;
            detail.Email = viewModel.Email;
            detail.Level = string.Empty;
            entities.UserDetails.AddObject(detail);
            entities.SaveChanges();
            return detail;

        }

        public static bool Activate(string username, string code)
        {
            WebCore.Models.DataEntities.DataEntities entities = new DataEntities.DataEntities();
            User user = (from r in entities.Users
                         where r.UserName == username
                         select r).FirstOrDefault();
            if (user == null) return false;
            //
            UserDetail userDetail = (from r in entities.UserDetails
                                     where r.UserID == user.UserId
                                     select r).FirstOrDefault();
            if (userDetail == null) return false;
            userDetail.State = MyAppConfig.State_Active;
            //
            entities.SaveChanges();
            //
            MembershipUser memUser = System.Web.Security.Membership.GetUser(username);
            if (memUser == null) return false;
            memUser.IsApproved = true;
            System.Web.Security.Membership.UpdateUser(memUser);
            //
            Roles.AddUserToRole(username, MyAppConfig.Role_Membership); // add to role member

            return true;
        }

        /*public static void AddPoint(string username, double point, string reason, string cartCode, string createdBy)
        {
            WebCore.Models.DataEntities.DataEntities entities = new DataEntities.DataEntities();

            User user = (from r in entities.Users
                         where r.UserName == username
                         select r).FirstOrDefault();

            AddPoint(user.UserId, point, reason, cartCode, createdBy);
        }

        public static void AddPoint(Guid userID, double point, string reason, string cartCode, string createdBy)
        {
            WebCore.Models.DataEntities.DataEntities entities = new DataEntities.DataEntities();

            DataEntities.UserPointHistory uph = new UserPointHistory();
            uph.UserPointHistoryID = Guid.NewGuid();
            if (!String.IsNullOrEmpty(createdBy))
                uph.CreateBy = GetUserDetail(createdBy).UserID.Value;
            uph.CreatedAt = DateTime.Now;
            uph.Point = point;
            uph.ProductCartCode = cartCode;
            uph.Reason = reason;
            uph.State = MyAppConfig.State_Active;
            uph.UserID = userID;

            entities.UserPointHistories.AddObject(uph);
            entities.SaveChanges();
        }*/

        public static bool ResetPassword(string email, ref string newPassword, ref string userName)
        {
            email = email.Trim().ToUpper();
            WebCore.Models.DataEntities.DataEntities entities = new DataEntities.DataEntities();
            UserDetail userDetail = (from r in entities.UserDetails
                                     where r.Email.ToUpper() == email
                                     select r).FirstOrDefault();
            if (userDetail == null) return false;
            User user = (from r in entities.Users
                         where r.UserId == userDetail.UserID
                         select r).FirstOrDefault();
            if (user == null) return false;
            MembershipUser mu = System.Web.Security.Membership.GetUser(user.UserName);
            newPassword = mu.ResetPassword();
            userName = user.UserName;
            System.Web.Security.Membership.UpdateUser(mu);
            return true;
        }

        public static List<UserDetail> FilterUserDetails(string key, string by, string role, string state)
        {
            List<UserDetail> result = new List<UserDetail>();
            WebCore.Models.DataEntities.DataEntities entities = new DataEntities.DataEntities();
            //

            //
            if (String.IsNullOrEmpty(key) && String.IsNullOrEmpty(role) && String.IsNullOrEmpty(state))
            {
                result = (from r in entities.UserDetails
                          select r).ToList();
            }
            else if (key.Length > 0)
            {
                key = key.ToLower();
                if (by == "AccountName")
                    result = (from ud in entities.UserDetails
                              join r in entities.Users on ud.UserID equals r.UserId
                              where ud.UserName.ToLower().Contains(key) && (ud.State == state || state == "")
                              select ud).ToList();
                else if (by == "Fullname")
                    result = (from ud in entities.UserDetails
                              join r in entities.Users on ud.UserID equals r.UserId
                              where ud.FullName.ToLower().Contains(key) && (ud.State == state || state == "")
                              select ud).ToList();
                else if (by == "Email")
                    result = (from ud in entities.UserDetails
                              join r in entities.Users on ud.UserID equals r.UserId
                              where ud.Email.ToLower().Contains(key) && (ud.State == state || state == "")
                              select ud).ToList();
                else if (by == "Phone")
                    result = (from ud in entities.UserDetails
                              join r in entities.Users on ud.UserID equals r.UserId
                              where (ud.HomePhone.Contains(key) || ud.HomeMobile.Contains(key)) && (ud.State == state || state == "")
                              select ud).ToList();
                else if (by == "Address")
                    result = (from ud in entities.UserDetails
                              join r in entities.Users on ud.UserID equals r.UserId
                              where ud.Address.ToLower().Contains(key) && (ud.State == state || state == "")
                              select ud).ToList();


            }
            else
            {
                result = (from ud in entities.UserDetails
                          join r in entities.Users on ud.UserID equals r.UserId
                          where (ud.State == state || state == "")
                          select ud).ToList();
            }
            // filter by role
            Role filterRole = null;
            if (role.Length > 0)
            {
                Guid roleID = new Guid(role);
                filterRole = (from r in entities.Roles
                              where r.RoleId == roleID
                              select r).FirstOrDefault();

                List<UserDetail> resultAfterRole = new List<UserDetail>();
                foreach (UserDetail ud in result)
                {
                    User u = (from r in entities.Users
                              where r.UserId == ud.UserID
                              select r).FirstOrDefault();
                    if (u.Roles.Contains(filterRole))
                    {
                        resultAfterRole.Add(ud);
                    }
                }
                //
                return resultAfterRole;
            }
            return result;
        }

        public static User GetUser(Guid userID)
        {
            WebCore.Models.DataEntities.DataEntities entities = new DataEntities.DataEntities();
            return (from r in entities.Users
                    where r.UserId == userID
                    select r).FirstOrDefault();
        }

        public static UserDetail GetUserDetail(Guid userDetailID)
        {
            WebCore.Models.DataEntities.DataEntities entities = new DataEntities.DataEntities();
            return (from r in entities.UserDetails
                    where r.UserDetailID == userDetailID
                    select r).FirstOrDefault();
        }

        public static DataEntities.Membership GetMembership(Guid userID)
        {
            WebCore.Models.DataEntities.DataEntities entities = new DataEntities.DataEntities();
            return (from r in entities.Memberships
                    where r.UserId == userID
                    select r).FirstOrDefault();
        }

        public static string GetRolesInText(Guid userID)
        {
            WebCore.Models.DataEntities.DataEntities entities = new DataEntities.DataEntities();
            User u = (from r in entities.Users
                      where r.UserId == userID
                      select r).FirstOrDefault();
            string result = string.Empty;
            foreach (Role r in u.Roles)
            {
                result = result + r.RoleName + ",";
            }
            if (result.Length > 0)
                result = result.Substring(0, result.Length - 1);
            return result;
        }

        public static List<Role> GetRoles()
        {
            WebCore.Models.DataEntities.DataEntities entities = new DataEntities.DataEntities();
            return (from r in entities.Roles
                    select r).ToList();
        }

        public static bool UpdateUserDetail(ViewModels.Admin.UserDetailViewModel viewModel, ref string errorCode)
        {
            WebCore.Models.DataEntities.DataEntities entities = new DataEntities.DataEntities();

            UserDetail ud = (from r in entities.UserDetails
                             where r.UserDetailID == viewModel.UserDetailID
                             select r).FirstOrDefault();
            ud.State = viewModel.UserState;
            MembershipUser mu = System.Web.Security.Membership.GetUser(ud.UserName);
            if (viewModel.UserState == MyAppConfig.State_Active)
            {
                //unlock
                mu.UnlockUser();
                mu.IsApproved = true;
                System.Web.Security.Membership.UpdateUser(mu);
            }
            else if (viewModel.UserState == MyAppConfig.State_Locked || viewModel.UserState == MyAppConfig.State_Inactive)
            {
                mu.IsApproved = false;
                System.Web.Security.Membership.UpdateUser(mu);
            }

            if (!String.IsNullOrEmpty(viewModel.NewPassword))
            {
                if (viewModel.NewPassword != viewModel.ConfirmPassword)
                {
                    errorCode = "NotMatchPassword";
                    return false;
                }

                mu.ChangePassword(mu.ResetPassword(), viewModel.NewPassword);
            }

            List<Role> roles = GetRoles();

            User u = GetUser(ud.UserID.Value);
            foreach (Role r in roles)
            {
                if (viewModel.Roles.Contains(r.RoleId.ToString() + ","))
                {
                    if (!Roles.IsUserInRole(ud.UserName, r.RoleName))
                        Roles.AddUserToRole(ud.UserName, r.RoleName);
                }
                else
                {
                    if (Roles.IsUserInRole(ud.UserName, r.RoleName))
                        Roles.RemoveUserFromRole(ud.UserName, r.RoleName);
                }
            }
            entities.SaveChanges();
            errorCode = string.Empty;
            return true;
        }

        //public static bool SaveMyInformation(ViewModels.MyInformationViewModel viewModel, ref string errorCode)
        //{
        //    WebCore.Models.DataEntities.DataEntities entities = new DataEntities.DataEntities();
        //    UserDetail ud = (from r in entities.UserDetails
        //                     where r.UserDetailID == viewModel.UserDetailID
        //                     select r).FirstOrDefault();
        //    ud.FullName = viewModel.FullName;
        //    ud.Gender = viewModel.Gender == "MALE" ? true : false;
        //    ud.HomeMobile = viewModel.PhoneMobile;
        //    ud.HomePhone = viewModel.PhoneHome;
        //    ud.Address = viewModel.Address;
        //    ud.BirthDate = DateTime.Parse(viewModel.BirthDate + "/" + viewModel.BirthMonth + "/" + viewModel.BirthYear);
        //    ud.Bank = viewModel.Bank;
        //    ud.BankAccountNumber = viewModel.BankAccountNumber;
        //    ud.BankAccountOwner = viewModel.BankAccountOwner;
        //    entities.SaveChanges();
        //    errorCode = string.Empty;
        //    return true;
        //}

        //public static bool SaveMyPassword(ViewModels.MyPasswordViewModel viewModel, ref string errorCode)
        //{
        //    if (viewModel.ConfirmPassword != viewModel.NewPassword)
        //    {
        //        errorCode = "NotMatchPassword";
        //        return false;
        //    }
        //    else if (viewModel.ConfirmPassword.Length < 6)
        //    {
        //        errorCode = "PasswordMustBeGreaterThanSix";
        //        return false;
        //    }
        //    MembershipUser mu = System.Web.Security.Membership.GetUser(viewModel.UserName);
        //    if (mu.ChangePassword(viewModel.OldPassword, viewModel.NewPassword))
        //        return true;
        //    else
        //    {
        //        errorCode = "Unknown";
        //        return false;
        //    }
        //}

        public static UserDetail GetUserDetailByUserID(Guid userID)
        {
            WebCore.Models.DataEntities.DataEntities entities = new DataEntities.DataEntities();
            return (from r in entities.UserDetails
                    where r.UserID == userID
                    select r).FirstOrDefault();
        }

        //public static List<UserPointHistory> FilterUserPointHistory(string userName, DateTime fromDate, DateTime toDate, string reason, string cartCode, string state)
        //{
        //    DataEntities.DataEntities entities = new DataEntities.DataEntities();
        //    toDate = toDate.AddHours(24);
        //    return (from h in entities.UserPointHistories
        //            join u in entities.Users on h.UserID equals u.UserId
        //            where (u.UserName.Contains(userName) || string.IsNullOrEmpty(userName))
        //            && (h.CreatedAt >= fromDate && h.CreatedAt <= toDate)
        //            && (h.Reason.Contains(reason) || reason == string.Empty)
        //            && (h.ProductCartCode.Contains(cartCode) || cartCode == string.Empty)
        //            && (h.State == state || state == string.Empty)
        //            orderby h.CreatedAt descending
        //            select h).ToList();
        //}

        //public static List<UserPointHistory> FilterActiveUserPointHistory(string userName)
        //{
        //    DataEntities.DataEntities entities = new DataEntities.DataEntities();

        //    return (from h in entities.UserPointHistories
        //            join u in entities.Users on h.UserID equals u.UserId
        //            where (u.UserName.Contains(userName) || string.IsNullOrEmpty(userName)) && h.State == MyAppConfig.State_Active
        //            orderby h.CreatedAt descending
        //            select h).ToList();
        //}

        //public static double? GetPoint(string userName)
        //{
        //    DataEntities.DataEntities entities = new DataEntities.DataEntities();
        //    return (from h in entities.UserPointHistories
        //            join u in entities.Users on h.UserID equals u.UserId
        //            where (u.UserName.Contains(userName) || string.IsNullOrEmpty(userName)) && h.State == MyAppConfig.State_Active
        //            select h).Sum(h => h.Point);

        //}
        //public static UserPointHistory GetUserPointHistoryDetail(Guid id)
        //{
        //    DataEntities.DataEntities entities = new DataEntities.DataEntities();

        //    return (from r in entities.UserPointHistories
        //            where r.UserPointHistoryID == id
        //            select r).FirstOrDefault();
        //}

        //public static void UpdateUserPointHistory(UserPointHistoryDetailViewModel viewModel)
        //{
        //    DataEntities.DataEntities entities = new DataEntities.DataEntities();

        //    UserPointHistory uph = (from r in entities.UserPointHistories
        //                            where r.UserPointHistoryID == viewModel.UserPointHistoryID
        //                            select r).FirstOrDefault();
        //    uph.State = viewModel.State;
        //    entities.SaveChanges();
        //}

        //public static void UpdatePointByCartItem(ProductCartItem pci, ProductCart pc)
        //{
        //    // if state = CartStateSuccess, update point for the user
        //    if (pc.UserID.HasValue)
        //    {
        //        NewsCategory stateSuccess = NewsManager.GetFirstCategory(NewsCategoryGroupEnum.CartStateSuccess, MyAppConfig.Lang_Current);
        //        Product p = ProductManager.GetProduct(pci.ProductID.Value);

        //        DataEntities.DataEntities entities = new DataEntities.DataEntities();
        //        // check existance
        //        UserPointHistory uph = (from r in entities.UserPointHistories
        //                                where r.ProductCartItemID == pci.ProductCartItemID
        //                                select r).FirstOrDefault();
        //        if (uph == null)
        //        {
        //            uph = new UserPointHistory();
        //            uph.UserPointHistoryID = Guid.NewGuid();
        //            uph.CreatedAt = DateTime.Now;
        //            uph.Point = pci.Point;
        //            uph.ProductCartCode = pc.ProductCartCode;
        //            uph.Reason = "Mua sản phẩm " + p.Name;
        //            uph.State = MyAppConfig.State_Inactive;
        //            uph.UserID = pc.UserID.Value;
        //            uph.ProductCartItemID = pci.ProductCartItemID;
        //            entities.UserPointHistories.AddObject(uph);
        //        }

        //        if (pci.State == stateSuccess.NewsCategoryID.ToString())
        //            uph.State = MyAppConfig.State_Active;
        //        else
        //            uph.State = MyAppConfig.State_Inactive;

        //        entities.SaveChanges();
        //    }
        //}
    }
}